<?php
use x\App;
use x\Config;
use x\Container;
use x\G;
use x\my\Format;
use x\my\Validate;

/**
 * 打印变量,断点
 * @param unknown $a 变量
 * @param string $b 是否打印变量类型
 */
function t($a, $b = false) {
	echo "<pre>";
	if ($b) {
		var_dump($a);
	} else {
		print_r($a);
	}
	exit("</pre>");
}

/**
 * 页面输出
 *
 * @param string $msg  信息
 * @param string $exit 是否阻断
 */
function e($msg = '', $exit = false) {
	if ($exit) {
		exit("------------------{$msg}-------------------<br>");
	} else {
		echo ("------------------{$msg}-------------------<br>");
	}
}

/**
 * URL重定向
 * @param string $url 重定向的URL地址
 * @param integer $time 重定向的等待时间（秒）
 * @param string $msg 重定向前的提示信息
 * @return 跳转页面
 */
function r($url, $time = 0, $msg = '') {
	if (empty($msg)) {
		$msg = "系统将在{$time}秒之后自动跳转到{$url}！";
	}

	if (!headers_sent()) {
		if (0 === $time) {
			header('Location: ' . $url);
		} else {
			header("refresh:{$time};url={$url}");
			echo ($msg);
		}
	} else {
		$str = "<meta http-equiv='Refresh' content='{$time};URL={$url}'>";
		if ($time != 0) {
			$str .= $msg;
		}
		echo ($str);
	}
	exit();
}

/**
 * 引入数据模型
 * @return [type] [description]
 */
function m($name, $layer = '', $vars = []) {
	$app = new App();
	return $app->model($name, $layer, $vars);
}

/**
 * 引入服务模型
 * @return [type] [description]
 */
function s($name, $layer = '', $vars = []) {
	$app = new App();
	return $app->server($name, $layer, $vars);
}

/**
 * 获取配置
 * @param string $name 配置一级键值的名称
 * @return \think\mixed
 */
function c($name = '') {
	$con = Config::get('', 2);
	$arr = explode('.', $name);
	$rs = [];
	if (isset($arr[0]) && isset($con[$arr[0]])) {
		$rs = $con[$arr[0]];
	}

	if (isset($arr[1]) && isset($con[$arr[0]][$arr[1]])) {
		$rs = $con[$arr[0]][$arr[1]];
	}

	if (isset($arr[2]) && isset($con[$arr[0]][$arr[1]][$arr[2]])) {
		$rs = $con[$arr[0]][$arr[1]][$arr[2]];
	}

	return $rs;
}
/**
 * 获取数据库配置
 * @param  string $uuid [小写配置]
 * @return [type]       [description]
 */
function sys($uuid = '') {
	if (!isset(G::$exts['sys'])) {
		G::$exts['sys'] = m('Deploy', 'xcom')->lists();
	}
	if ($uuid) {
		return G::$exts['sys'][strtolower($uuid)];
	} else {
		return G::$exts['sys'];
	}
}

//获取链接类型
function get_http_type() {
	return ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';
}

//新建链接
function url($url, $vars = [], $domain = false, $is_https = false) {
	//路由模块判断
	$arr = array_filter(explode('/', $url));
	#一级域名
	if (G::$web_site_id) {
		if (count($arr) == 2) {
			array_unshift($arr, G::$m);
		}
		if (count($arr) != 3) {
			exit('err url!');
		}
		$url = implode("/", $arr);
		#二级域名
	} else {
		if (count($arr) == 3) {
			array_shift($arr);
		}
		if (count($arr) != 2) {
			exit('err url!');
		}
		$url = implode("/", $arr);
	}
	$url .= ".html";
	$str = '';
	if ($vars) {
		$str = '?';
		foreach ($vars as $k => $v) {
			$str .= "$k=$v&";
		}
		$str = rtrim($str, '&');
	}
	$domain = $domain?$domain:DOMAIN;
	return get_http_type() . $domain . '/' . $url . $str;
	//return $is_https ? 'https://' . DOMAIN . '/' . $url . $str : 'http://' . DOMAIN . '/' . $url . $str;
}
//成功,失败跳转
function jump($msg = '操作成功', $url = '', $type = 0, $wait = 3) {
	clear_cookie_arr('jump');
	cookie('jump_msg', $msg);
	cookie('jump_type', $type);
	cookie('jump_url', $url);
	cookie('jump_wait', $wait);
	$type ? r(url('jump/error')) : r(url('jump/success'));
}

// js跳转页面
function js_url($url = '', $second = 1) {
	$s = bcmul($second, 1000);
	if ($url) {
		exit("<script>setTimeout(function(){window.location.href='" . $url . "';}," . $s . ");</script>");
	} else {
		exit("<script>setTimeout('window.location.reload();'," . $s . ");</script>");
	}
}
// 说明：获取完整URL
function com_cur_url() {
	$pageURL = 'http';

	if ((!empty($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] == 'https')) {
		$pageURL .= "s";
	}

	$pageURL .= "://";

	if ($_SERVER["SERVER_PORT"] != "80") {
		$pageURL .= $_SERVER["HTTP_HOST"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
	} else {
		$pageURL .= $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
	}
	return $pageURL;
}

//获取env的变量
function env($key = '') {
	#加载配置
	$config = include APP_PATH . '../Env.php';
	$default = include __dir__ . '/Default.php';
	$config = array_merge($default, $config);

	$arr = explode('.', $key);
	$rs = $config;
	if (isset($arr[0]) && isset($config[$arr[0]])) {
		$rs = $config[$arr[0]];
	}

	if (isset($arr[1]) && isset($config[$arr[1]])) {
		$rs = $config[$arr[1]];
	}

	//固定Ipvdebug为 true
	if ($arr[0] == 'debug') {
		if (in_array(ip(), $config['debug_true_ip'])) {
			return true;
		}
	}
	return $rs;
}
//图片地址完整路径
function pic($url) {
	if (stripos($url, 'http') === false) {
		$url = get_http_type() . DOMAIN . '/' . $url;
	}
	return $url;
}
/**
 * Session管理
 * @param string|array  $name session名称，如果为数组表示进行session设置
 * @param mixed         $value session值
 * @param string        $prefix 前缀
 * @return mixed
 */
function session($name, $value = '') {
	$app = Container::get(App::class);
	$session = Container::get('x\my\Session');
	$session->prefix($app->m);
	if (is_null($name)) {
		// 清除
		$session->clear($value);
	} elseif ('' === $value) {
		// 判断或获取
		return 0 === strpos($name, '?') ? $session->has(substr($name, 1)) : $session->get($name);
	} elseif (is_null($value)) {
		// 删除
		return $session->delete($name);
	} else {
		// 设置
		return $session->set($name, $value);
	}
}
/**
 * Cookie管理
 * @param string|array  $name cookie名称，如果为数组表示进行cookie设置
 * @param mixed         $value cookie值
 * @param mixed         $option 参数
 * @return mixed
 */
function cookie($name, $value = '', $dbtype = false, $option = null, $m = '') {
	$app = Container::get(App::class);
	$cookie = Container::get('x\my\Cookie');
	if ($m) {
		$cookie->init($m . '_', $dbtype);
	} else {
		$cookie->init($app->m . '_', $dbtype);
	}
	if (is_null($name)) {
		// 清除
		$cookie->clear();
	} elseif ('' === $value) {
		// 获取
		return 0 === strpos($name, '?') ? $cookie->has(substr($name, 1), $option) : $cookie->get($name);
	} elseif (is_null($value)) {
		// 删除
		return $cookie->delete($name);
	} else {
		// 设置
		return $cookie->set($name, $value, $option);
	}
}
/**
 * 产生token值
 * @param string $user_id 用户id, 或者其他
 */
function token($user_id = '') {
	$str = microtime(true) . uniqid($_SERVER['REMOTE_ADDR'] . '_' . $_SERVER['REMOTE_PORT'] . '_' . getmypid() . '_' . mt_rand() . '_', true) . rand(1000, 9999) . $user_id;
	return md5($str);
}

//验证参数
function check($rule, $msg, $data) {
	$validate = Validate::make($rule, $msg);
	//t([$rule,$msg,$data]);
	$result = $validate->check($data);
	//t($result,1);
	if (!$result) {
		err($validate->getError());
	}
}

//获取数据库对象
function db($config = []) {
	if (!$config) {
		$config = env('db');
	}
	$db = Container::get('x\db\driver\Mysqlidb')->init($config);
	return $db;
}
function com_sql() {
	db()->getSql();
}

function ip() {
	$ip = '未知IP';
	if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
		return is_ip($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : $ip;
	} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
		return is_ip($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $ip;
	} else {
		return is_ip($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : $ip;
	}
}
function is_ip($str) {
	$ip = explode('.', $str);
	for ($i = 0; $i < count($ip); $i++) {
		if ($ip[$i] > 255) {
			return false;
		}
	}
	return preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/', $str);
}
/**
 * 是否是AJAx提交的
 * @return bool
 */
function is_ajax() {
	if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
		return true;
	} else {
		return false;
	}
}
/**
 * 是否是GET提交的
 */
function is_get() {
	return $_SERVER['REQUEST_METHOD'] == 'GET' ? true : false;
}
/**
 * 是否是POST提交
 * @return int
 */
function is_post() {
	return isset($_SERVER['REQUEST_METHOD']) && !strcasecmp($_SERVER['REQUEST_METHOD'], 'POST');
}
/**
 * 判断是否是手机
 * @return boolean [description]
 */
function is_phone() {
	// 如果有HTTP_X_WAP_PROFILE则一定是移动设备
	if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
		return true;
	}
	// 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
	if (isset($_SERVER['HTTP_VIA']) && stristr($_SERVER['HTTP_VIA'], "wap")) {
		// 找不到为flase,否则为true
		return true;
	}
	// 脑残法，判断手机发送的客户端标志,兼容性有待提高。其中'MicroMessenger'是电脑微信
	if (isset($_SERVER['HTTP_USER_AGENT'])) {
		$clientkeywords = array('nokia', 'sony', 'ericsson', 'mot', 'samsung', 'htc', 'sgh', 'lg', 'sharp', 'sie-', 'philips', 'panasonic', 'alcatel', 'lenovo', 'iphone', 'ipod', 'blackberry', 'meizu', 'android', 'netfront', 'symbian', 'ucweb', 'windowsce', 'palm', 'operamini', 'operamobi', 'openwave', 'nexusone', 'cldc', 'midp', 'wap', 'mobile', 'MicroMessenger');
		// 从HTTP_USER_AGENT中查找手机浏览器的关键字
		if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
			return true;
		}
	}
	// 协议法，因为有可能不准确，放到最后判断
	if (isset($_SERVER['HTTP_ACCEPT'])) {
		// 如果只支持wml并且不支持html那一定是移动设备
		// 如果支持wml和html但是wml在html之前则是移动设备
		if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
			return true;
		}
	}
	return false;
}
function isCli() {
	return PHP_SAPI == 'cli';
}
function isCgi() {
	return strpos(PHP_SAPI, 'cgi') === 0;
}
// 是否是微信
function is_weixin() {
	return strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false ? true : false;
}
//验证手机号是否正确
function check_phone($number) {
	return preg_match("/^1[34578]\d{9}$/", $number);
}
/**
 * 计算年龄
 * @param  [type] $birthday [description]
 * @return [type]           [description]
 */
function get_age($birthday){
	list($by,$bm,$bd) = explode("-",date('Y-m-d',$birthday));
	list($ty,$tm,$td) = explode("-",date('Y-m-d',time()));
	$age = $ty-$by;
	if($bm>$tm || ($bm==$tm && $bd>$td)){
		$age--;
	}
	return $age;
}
/**
 * 微信签名
 * @param [type] $array 需签名的数组
 * @param [type] $str   key为商户平台设置的密钥key
 */
function wx_sign($data, $key) {
	ksort($data);
	$buff = '';
	foreach ($data as $k => $v) {
		$buff .= ($k != 'sign' && $v != '' && !is_array($v)) ? $k . '=' . $v . '&' : '';
	}
	$str = trim($buff, '&');
	$string = md5($str . '&key=' . $key);
	return strtoupper($string);
}

// 验证数组是否有为空或0的
function check_arr($arr = []) {
	foreach ($arr as $v) {
		if (!$v) {
			return false;
		}

	}
	return true;
}

//组装limit
function limit($page, $limit = 12) {
	$limit = $limit ? $limit : 12;
	$start = ($page - 1) * $limit;
	$str = " limit $start, $limit ";
	return $str;
}
/**
 * 组装where条件
 * @param  [type] $map
 *         $map = [
 *             ['and', 'id',  '=',1], #各种比较符>,<,=,!=
 *             ['and',  'name','like',"%张三%"], #like条件
 *             ['and', 'id', 'in', [1,"2",3]], #in, not in
 *             ['or', "(username=? or username like ?)", ['张三', "%张%"]] #复合条件
 *         ];
 * @return [type][数组]
 */
function where($map) {
	$temp = ['', []];
	if ($map) {
		$str = ' where ';
		foreach ($map as $v) {
			$v[2] = is_string($v[2]) ? strtolower($v[2]) : $v[2];
			#连接条件
			$v[0] = strtolower($v[0]);
			#in条件
			if (($v[2] == 'in' or $v[2] == 'not in') && is_array($v[3])) {
				$str .= " {$v[0]} {$v[1]} {$v[2]}(";
				foreach ($v[3] as $val) {
					$str .= "?,";
					$temp[1][] = $val;
				}
				$str = rtrim($str, ',');
				$str .= ")";
				#like条件
			} elseif ($v[2] == 'like') {
				$str .= " {$v[0]} ( ";
				$arr = explode("|", $v[1]);
				foreach ($arr as $val) {
					$str .= " " . field_key($val) . " like ? or";
					$temp[1][] = $v[3];
				}
				$str = rtrim($str, 'or');
				$str .= ")";
				#复合条件
			} elseif (is_array($v[2])) {
				$str .= " {$v[0]} {$v[1]} ";
				foreach ($v[2] as $val) {
					$temp[1][] = $val;
				}
				#正常的条件
			} else {
				$str .= " {$v[0]} " . field_key($v[1]) . " {$v[2]} ?  ";
				$temp[1][] = $v[3];
			}
		}
		$str = preg_replace("/and|or/", "", $str, 1);
		$str = $str . " ";
		$temp[0] = $str;
	}
	return $temp;
}
function field_key($field) {
	$arr = explode(".", $field);
	if (isset($arr[1])) {
		$rs = $arr[0] . ".`{$arr[1]}`";
	} else {
		$rs = "`{$arr[0]}`";
	}
	return $rs;
}
function countZwf($arr) {
	$temp = [];
	foreach ($arr as $v) {
		$temp[] = "?";
	}
	return implode(",", $temp);
}

//api常用函数 +----------------------------------------------------------------------
function err($msg = '未知错误', $code = 100) {
	if (isset(G::$exts['api_version'])) {
		$temp = ['code' => $code, 'version' => G::$exts['api_version'], 'msg' => $msg, 'data' => []];
	} else {
		$js = get_cookie_arr('js');
		$temp = ['code' => $code, 'js' => $js, 'msg' => $msg, 'data' => []];
	}
	if (env('debug') && isset(G::$exts['api_url_id'])) {
		db()->update('log_test', ['tocontent' => json_encode($temp, JSON_UNESCAPED_UNICODE)], ['api_url_id=?', [G::$exts['api_url_id']]]);
	}
	header('Content-Type:application/json; charset=utf-8');
	exit(json_encode($temp, JSON_UNESCAPED_UNICODE));
}
function suc($data = [], $count = 0) {
	$count = (int) $count;
	if ($data == null || $data == '') {
		$data = [];
	}

	if (isset(G::$exts['api_version'])) {
		$temp = ['code' => 0, 'version' => G::$exts['api_version'], 'msg' => '操作成功', 'data' => $data, 'count' => $count];
	} else {
		$js = get_cookie_arr('js');
		$temp = ['code' => 0, 'js' => $js, 'msg' => '操作成功', 'data' => $data, 'count' => $count];
	}
	if (env('debug') && isset(G::$exts['api_url_id'])) {
		db()->update('log_test', ['tocontent' => json_encode($temp, JSON_UNESCAPED_UNICODE)], ['api_url_id=?', [G::$exts['api_url_id']]]);
	}
	header('Content-Type:application/json; charset=utf-8');
	exit(json_encode($temp, JSON_UNESCAPED_UNICODE));
}

//计入日志表
function log_test($uuid, $data = []) {
	if (!env('debug')) {
		return;
	}

	$data = $data ? $data : $_REQUEST;
	$data = obj_array($data);
	$url = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
	$d = [
		'uuid' => $uuid,
		'api_url_id' => isset(G::$exts['api_url_id']) ? G::$exts['api_url_id'] : '',
		'url' => $url,
		'content' => json_encode($data, JSON_UNESCAPED_UNICODE),
		'create_time' => time(),
	];
	db()->insert('log_test', $d);
}
/**
 * 对象转数组
 * @param  [type] $data [description]
 * @return [type]      [description]
 */
function obj_array($data) {
	return is_object($data) ? json_decode(json_encode($data, JSON_UNESCAPED_UNICODE), true) : (is_array($data) ? $data : [$data]);
}
//获取多个编组的cookie,组成数组
function get_cookie_arr($key) {
	$app = Container::get(App::class);
	$str = $app->m . '_' . $key . '_';
	$temp = [];
	foreach ($_COOKIE as $k => $v) {
		$name = strstr($k, $str);
		if ($name) {
			$temp[str_replace($str, '', $name)] = $v;
		}
	}
	return $temp;
}
//清除数组cookie
function clear_cookie_arr($key) {
	$app = Container::get(App::class);
	$str = $app->m . '_' . $key . '_';
	foreach ($_COOKIE as $k => $v) {
		$name = strstr($k, $str);
		if ($name) {
			cookie(str_replace($app->m . '_', '', $k), null);
		}
	}
}
/**
 * 简单对称加密算法之加密
 * @param String $string 需要加密的字串
 * @param String $skey 加密EKY
 * @return String
 */
function encode($string = '', $skey = 'abcd') {
	$strArr = str_split(base64_encode($string));
	$strCount = count($strArr);
	foreach (str_split($skey) as $key => $value) {
		$key < $strCount && $strArr[$key] .= $value;
	}

	return str_replace(array('=', '+', '/'), array('O0O0O', 'o000o', 'oo00o'), join('', $strArr));
}

/**
 * 简单对称加密算法之解密
 * @param String $string 需要解密的字串
 * @param String $skey 解密KEY
 * @return String
 */
function decode($string = '', $skey = 'abcd') {
	$strArr = str_split(str_replace(array('O0O0O', 'o000o', 'oo00o'), array('=', '+', '/'), $string), 2);
	$strCount = count($strArr);
	foreach (str_split($skey) as $key => $value) {
		$key <= $strCount && isset($strArr[$key]) && $strArr[$key][1] === $value && $strArr[$key] = $strArr[$key][0];
	}

	return base64_decode(join('', $strArr));
}

/**
 * 签名
 * @param unknown $data 数组
 * @param unknown $keys app key值
 * @return true or false
 */
function sign_bak($data, $keys) {
	#配置: '应用编号'=>'秘钥',
	$app_config = [
		"5100" => 'ios_app_secret', #ios
		"5200" => 'android_app_secret', #安卓
		"5300" => 'h5_app_secret', #h5
		"5400" => 'pc_app_secret', #pc
	];
	if (isset($data['sign'])) {
		unset($data['sign']);
	}

	if (isset($data['app_key'])) {
		unset($data['app_key']);
	}

	$temp_k = array_keys($data);
	sort($temp_k);
	$str = $keys;
	foreach ($temp_k as $k) {
		if (isset($data[$k]) && is_string($data[$k])) {
			$str .= $k . $data[$k];
		}

	}
	$str .= $app_config[$keys];
	return strtoupper(sha1($str));
}

/**
 * 格式化字节大小
 * @param  number $size 字节数
 * @param  string $delimiter 数字和单位分隔符
 * @return string            格式化后的带单位的大小
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function format_bytes($size, $delimiter = '') {
	$units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
	for ($i = 0; $size >= 1024 && $i < 5; $i++) {
		$size /= 1024;
	}
	return $size . $delimiter . $units[$i];
}

/**
 * 截取字符 /**1234/
 * @param [type] $str
 */
function com_format_str($str, $front = 3, $back = 4) {
	$str = (string) $str;
	$strlen = mb_strlen($str, 'utf-8');
	if ($strlen <= ($front + $back)) {
		return $str;
	}
	$midstr = "";
	for ($i = 0; $i < $strlen - $front - $back; $i++) {
		$midstr .= "*";
	}
	return mb_substr($str, 0, $front, 'utf-8') . $midstr . mb_substr($str, -$back, $back, 'utf-8');
}

function send_sms() {

}

/**
 * 字符串截取，支持中文和其他编码
 * @param string $str 需要转换的字符串
 * @param int|string $start 开始位置
 * @param string $length 截取长度
 * @param string $charset 编码格式
 * @param bool|string $suffix 截断显示字符
 * @return string
 */
function msubstr($str, $start = 0, $length, $charset = "utf-8", $suffix = true) {
	if (function_exists("mb_substr")) {
		$slice = mb_substr($str, $start, $length, $charset);
	} elseif (function_exists('iconv_substr')) {
		$slice = iconv_substr($str, $start, $length, $charset);
		if (false === $slice) {
			$slice = '';
		}
	} else {
		$re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
		$re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
		$re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
		$re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
		preg_match_all($re[$charset], $str, $match);
		$slice = join("", array_slice($match[0], $start, $length));
	}
	return $suffix ? $slice . '...' : $slice;
}

/**
 *  不区分大小写的in_array实现
 * @author staitc7 <static7@qq.com>
 * @param $value
 * @param $array
 * @return bool
 */
function in_array_case($value, $array = []) {
	return in_array(strtolower($value), array_map('strtolower', $array ? $array : []));
}
/**
 *  分析枚举类型配置值
 *  格式 a:名称1,b:名称2
 * @param string $string 配置值
 * @return array
 */
function parse_config_attr($string) {
	$array = preg_split('/[,;\r\n]+/', trim($string, ",;\r\n"));
	if (strpos($string, ':')) {
		$value = [];
		foreach ($array as $val) {
			list($k, $v) = explode(':', $val);
			$value[$k] = $v;
		}
	} else {
		$value = $array;
	}
	return $value;
}
/** Json数据格式化
 * @param  Mixed  $data   数据
 * @param  String $indent 缩进字符，默认4个空格
 * @return JSON
 */
function jsonFormat($data, $indent = null) {
	$data = urldecode($data);
	// 缩进处理
	$ret = '';
	$pos = 0;
	$length = strlen($data);
	$indent = isset($indent) ? $indent : '    ';
	$newline = "\n";
	$prevchar = '';
	$outofquotes = true;
	for ($i = 0; $i <= $length; $i++) {
		$char = substr($data, $i, 1);
		if ($char == '"' && $prevchar != '\\') {
			$outofquotes = !$outofquotes;
		} elseif (($char == '}' || $char == ']') && $outofquotes) {
			$ret .= $newline;
			$pos--;
			for ($j = 0; $j < $pos; $j++) {
				$ret .= $indent;
			}
		}
		$ret .= $char;
		if (($char == ',' || $char == '{' || $char == '[') && $outofquotes) {
			$ret .= $newline;
			if ($char == '{' || $char == '[') {
				$pos++;
			}

			for ($j = 0; $j < $pos; $j++) {
				$ret .= $indent;
			}
		}
		$prevchar = $char;
	}
	return $ret;
}
/**
 * 把返回的数据集转换成Tree
 * @param array $list 要转换的数据集
 * @param string $pk
 * @param string $pid parent标记字段
 * @param string $child level标记字段
 * @param int $root 根
 * @return array
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function list_to_tree($list, $pk = 'id', $pid = 'pid', $child = '_child', $root = 0) {
	// 创建Tree
	$tree = [];
	if (is_array($list)) {
		// 创建基于主键的数组引用
		$refer = [];
		foreach ($list as $key => $data) {
			$refer[$data[$pk]] = &$list[$key];
		}
		foreach ($list as $key => $data) {
			// 判断是否存在parent
			$parentId = $data[$pid];
			if ($root == $parentId) {
				$tree[] = &$list[$key];
			} else {
				if (isset($refer[$parentId])) {
					$parent = &$refer[$parentId];
					$parent[$child][] = &$list[$key];
				}
			}
		}
	}
	return $tree;
}

/**
 * 系统非常规MD5加密方法
 * @param  string $str 要加密的字符串
 * @param string $key 默认密钥
 * @return string
 */
function com_password($str = '123456', $key = 'abcd') {
	return (string) $str === '' ? '' : md5(sha1($str) . $key);
}

/**
 * 时间戳格式化
 * @param int $time
 * @param string $format 时间格式, f:友好
 * @return string 完整的时间显示
 */
function com_time_format($time = null, $format = 'Y-m-d H:i:s') {
	if ((int) $time < 1) {
		return '';
	}

	if ($format == 'f') {
		$now = time();
		$day = date('Y-m-d', $time);
		$today = date('Y-m-d');

		$dayArr = explode('-', $day);
		$todayArr = explode('-', $today);
		//距离的天数，这种方法超过30天则不一定准确，但是30天内是准确的，因为一个月可能是30天也可能是31天
		$days = ($todayArr[0] - $dayArr[0]) * 365 + (($todayArr[1] - $dayArr[1]) * 30) + ($todayArr[2] - $dayArr[2]);
		//距离的秒数
		$secs = $now - $time;
		if (abs($now - $time) / 86400 > 3 || $days > 3) {
//跨年且超过3天
			return date('Y-m-d', $time);
		} else {

			if ($days < 1) {
//今天
				if ($secs < 60) {
					return $secs . '秒前';
				} elseif ($secs < 3600) {
					return floor($secs / 60) . "分钟前";
				} else {
					return floor($secs / 3600) . "小时前";
				}

			} else if ($days < 2) {
//昨天
				$hour = date('H', $time);
				return "昨天" . $hour . '点';
			} elseif ($days < 3) {
//前天
				$hour = date('h', $time);
				return "前天" . $hour . '点';
			} else {
//三天前
				return date('Y年m月d号', $time);
			}
		}
	} elseif ($format == 'w') {
		$w = date('w', $time);
		$day = "";
		switch ($w) {
		case 0:
			$day = '周日';
			break;
		case 1:
			$day = '周一';
			break;
		case 2:
			$day = '周二';
			break;
		case 3:
			$day = '周三';
			break;
		case 4:
			$day = '周四';
			break;
		case 5:
			$day = '周五';
			break;
		case 6:
			$day = '周六';
			break;
		}
		return $day;
	} else {
		return date($format, $time);
	}
}

/**
 * 格式化数字
 * @param  [type] $num  [description]
 * @param  string $type [description]
 * @return [type]       [description]
 */
function com_num_format($num, $type = 'phone') {
	if ($type == 'phone') {
		$num = preg_replace("/([0-9]{3})([0-9]{4})([0-9]{4})/", "$1 $2 $3", $num);
	}
	return $num;
}

/**
 * 格式化金额
 */
function com_money($num = "100", $pos = 4, $sign = '') {
	if (!is_numeric($num)) {
		return 0;
	}

	$str = sprintf("%." . $pos . "f", substr(sprintf("%." . ($pos + 2) . "f", $num), 0, -2));
	$str = (float) $str;
	return $sign . $str;
}
/**
 * 格式化金额
 *
 * @param int $money
 * @param int $len
 * @param string $sign
 * @return string
 */
function format_money($money, $len = 2, $sign = '￥') {
	$negative = $money > 0 ? '' : '-';
	$int_money = intval(abs($money));
	$len = intval(abs($len));
	$decimal = ''; //小数
	if ($len > 0) {
		$decimal = '.' . substr(sprintf('%01.' . $len . 'f', $money), -$len);
	}
	$tmp_money = strrev($int_money);
	$strlen = strlen($tmp_money);
	for ($i = 3; $i < $strlen; $i += 3) {
		$format_money .= substr($tmp_money, 0, 3) . ',';
		$tmp_money = substr($tmp_money, 3);
	}
	$format_money .= $tmp_money;
	$format_money = strrev($format_money);
	return $sign . $negative . $format_money . $decimal;
}

//获取某月开始结束时间
function month_time($ym = '') {
	$ym = $ym ? $ym : date("Y-m");
	$start_time = strtotime($ym . "-01 00:00:00");
	$end_time = strtotime(date("Ymt 23:59:59", $start_time));
	$data = [
		'start_time' => $start_time,
		'end_time' => $end_time,
	];
	return $data;
}

//获取某月开始结束时间
function day_time($ymd = '') {
	$ymd = $ymd ? $ymd : date("Y-m-d");
	$start_time = strtotime($ymd . " 00:00:00");
	$end_time = strtotime(date(" 23:59:59", $start_time));
	$data = [
		'start_time' => $start_time,
		'end_time' => $end_time,
	];
	return $data;
}

/**
 * 截取中间字符 /1**1/
 * @param [type] $str
 */
function com_strlen($str, $front = 3, $back = 4) {

	$str = (string) $str;
	$strlen = mb_strlen($str, 'utf-8');
	if ($strlen <= ($front + $back)) {
		return $str;
	}

	$midstr = "";
	for ($i = 0; $i < $strlen - $front - $back; $i++) {
		$midstr .= "*";
	}

	return mb_substr($str, 0, $front, 'utf-8') . $midstr . mb_substr($str, -$back, $back, 'utf-8');
}

/**
 * 下载excle
 * @param unknown $data 内容
 * @param unknown $title 标题
 * @param unknown $field 内容的过滤字段
 * @param unknown $type 文件位置/文件名
 * @return 返回文件的绝对路径
 */
function com_csv($data, $title = [], $field = [], $type) {
	$content = "";
	// 标题
	foreach ($title as $val) {
		$content .= $val . ",";
	}
	$content = rtrim($content, ",") . "\r\n";
	// 内容
	foreach ($data as $val) {
		foreach ($field as $f) {
			$temp_f = str_replace(array(","), array(""), $val[$f]);
			if (in_array($f, ["bank_no", "order_no", "phone", "kd_no"])) {
				$temp_f = "'" . $temp_f;
			}
			$content .= "\"" . $temp_f . "\",";
		}
		$content = rtrim($content, ",") . "\r\n";
	}
	$path = "uploads/csv/" . date("Y-m") . "/" . date("d");
	$dir = APP_PATH . "../public/" . $path;
	com_mkdir($dir);
	$file = $type . "_" . time() . ".csv";
	$filename = $dir . "/" . $file;
	file_put_contents($filename, mb_convert_encoding($content, "gbk", "utf-8"));
	return "http://{$_SERVER['HTTP_HOST']}/{$path}/{$file}";
}

/**
 * 按规则格式化返回数据
 * @param  [type] $data [description]
 * @param  [type] $rule [description]
 * @return [type]       [description]
 */
function com_format($data, $rule, $ext = []) {
	return Format::make($data, $rule, $ext);
}
/**
 * 递归创建目录
 * @param unknown $dir 文件路径
 * @return true or false
 */
function com_mkdir($dir) {
	if (is_dir($dir) || @mkdir($dir)) {
		return true;
	}

	if (!com_mkdir(dirname($dir))) {
		return false;
	}

	$rs = @mkdir($dir, 0777);
	chmod($dir, 0777);
	return $rs;
}

/**
 * 生成订单号
 * @return string
 */
function com_order_no($pre = '', $is_db = false) {
	if ($is_db) {
		$rs = db()->query('select id,preset_code from com_code limit 1', [], 1);
		if (!$rs) {
			return min(100000000000, 999999999999);
		}

		db()->delete('preset_code', $rs['id']);
		return $rs['code'];
	}
	$id = db()->insert('temp_id', ['t' => 1]);
	return $pre . date('Ymd') . (100000000 + $id);
}

/**
 * 远程采集图片到临时文件
 * @param string $url
 * @param string $filename
 * @return string|\my\false;
 */
function com_fetch_pic($url = '', $filename = "./uploads/temp/temp.png") {
	if (!$url) {
		return '';
	}

	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_HEADER, false);
	curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; SeaPort/1.2; Windows NT 5.1; SV1; InfoPath.2)");
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
	$data = curl_exec($ch);
	if (curl_errno($ch) !== 0) {
		return '';
	}
	curl_close($ch);
	$ext = strrchr($url, ",");
	$ext = in_array($ext, ['.gif', '.jpg', '.bmp', '.png']) ? $ext : ".jpg";
	$dir = dirname($filename);
	com_mkdir($dir);
	file_put_contents($filename, $data);
	return $filename;
}
